﻿/*
Usage :
Youtube API Reference :: http://code.google.com/intl/zh-TW/apis/youtube/flash_api_reference.html#setPlaybackQuality

function ::
this.init(Embedded);	// Embedded true|false
this.RELEASE();			// to destory whole player. auto release when remove form scene
this.chromeless();		// Chromeless - without control panel
this.embedded();		// embedded - with control panel
this.cueVideoById(_videoId:String, _startSeconds:Number=0, _suggestedQuality:String=DEFAULT)
this.loadVideoById(_videoId:String, _startSeconds:Number=0, _suggestedQuality:String=DEFAULT)
this.cueVideoByUrl(_mediaContentUrl:String, _startSeconds:Number=0)
this.loadVideoByUrl(_mediaContentUrl:String, _startSeconds:Number=0)
this.cuePlaylist(_playlist:*, _index:Number=0, _startSeconds:Number=0, _suggestedQuality:String=DEFAULT)
this.loadPlaylist(_playlist:*, _index:Number=0, _startSeconds:Number=0, _suggestedQuality:String=DEFAULT)
this.playVideo()
this.pauseVideo()
this.stopVideo()
this.seekTo(_seconds:Number, _allowSeekAhead:Boolean=true)
this.nextVideo()
this.previousVideo()
this.playVideoAt(_index:Number)
this.mute()
this.unMute()
this.setVolume(_volume:Number)
this.setSize(_tWidth:Number, _tHeight:Number)
this.setLoop(_loopPlaylists:Boolean)
this.setShuffle(_shufflePlaylist:Boolean)
this.setPlaybackQuality(_suggestedQuality:String)


value ::
this.inited				// return true|false base on G_inited
this.isMuted
this.getVolume
this.getVideoBytesLoaded
this.getVideoBytesTotal
this.getVideoStartBytes
this.getPlayerState
this.getCurrentTime
this.getPlaybackQuality
this.getAvailableQualityLevels
this.getDuration
this.getVideoUrl
this.getVideoEmbedCode
this.getPlaylist
this.getPlaylistIndex



*/
package com.cf.core.media{
	import flash.display.Sprite;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.system.Security;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import com.cf.core.Utils.tools;
	import com.cf.core.Utils.cache;
	import com.cf.core.Utils.debug;
	import com.cf.core.events.LoadEvent;
	
	public class youtubeAPI extends Sprite {
		// This will hold the API player instance once it is initialized.;
		private var G_player:Object;
		private var G_loader:Loader;
		private var G_inited:Boolean;
		private var G_PlayerReady:Boolean;
		private var G_config_playlist:Array;
		
		// Playback Quality Level
		public static const DEFAULT:String = "default";
		public static const SMALL:String = "small";
		public static const MEDIUM:String = "medium";
		public static const LARGE:String = "large";
		public static const HD720:String = "hd720";
		public static const HD1080:String = "hd1080";
		public static const HIGHRES:String = "highres";
		// End - Playback Quality Level
		
		public static const SPL:String = "[@]";
		
		public function youtubeAPI():void {
			// The player SWF file on www.youtube.com needs to communicate with your host
			// SWF file. Your code must call Security.allowDomain() to allow this
			// communication.
			// More info on : http://code.google.com/intl/zh-TW/apis/youtube/flash_api_reference.html
			Security.allowDomain("www.youtube.com");
			this.RELEASE();
		}//fn
		private function setupLoader():void{
			G_loader=new Loader();
			G_loader.contentLoaderInfo.addEventListener(Event.INIT, handleOnLoaderInit);
		}//fn
		public function init(_embedded:Boolean=true):void{
			if(_embedded) embedded(); else chromeless();
		}//fn
		public function chromeless():void{	// Chromeless
			if(inited) this.RELEASE();
			setupLoader();
			G_loader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3"));
			this.addEventListener(Event.ADDED_TO_STAGE, handleAddStage);
			G_inited=true;
		}//fn
		public function embedded():void{	// Embedded
			if(inited) this.RELEASE();
			setupLoader();
			G_loader.load(new URLRequest("http://www.youtube.com/v/NULL__VIDEO?version=3"));
			this.addEventListener(Event.ADDED_TO_STAGE, handleAddStage);
			G_inited=true;
		}//fn
		public function RELEASE(e:*=null):void{
			G_inited=false;
			G_PlayerReady=false;
			G_config_playlist=new Array();
			try{ G_player.destroy(); }catch(e){}
			try{ G_loader.unload(); }catch(e){}
			try{ tools.emptySprite(this); }catch(e){}
			G_player=new Object();
		}//fn
		
		// API function transfer
		public function get inited():Boolean{return G_inited}
		public function cueVideoById(_videoId:String, _startSeconds:Number=0, _suggestedQuality:String=DEFAULT):void{
			if(inited && G_PlayerReady) G_player.cueVideoById(_videoId, _startSeconds, _suggestedQuality);
			else{
				G_config_playlist.push("cueVideoById"+SPL+_videoId+SPL+_startSeconds+SPL+_suggestedQuality);
			}//if
		}//fn
		public function loadVideoById(_videoId:String, _startSeconds:Number=0, _suggestedQuality:String=DEFAULT):void{
			if(inited && G_PlayerReady) G_player.loadVideoById(_videoId, _startSeconds, _suggestedQuality);
			else{
				G_config_playlist.push("loadVideoById"+SPL+_videoId+SPL+_startSeconds+SPL+_suggestedQuality);
			}//if
		}//fn
		public function cueVideoByUrl(_mediaContentUrl:String, _startSeconds:Number=0):void{
			if(inited && G_PlayerReady) G_player.cueVideoByUrl(_mediaContentUrl, _startSeconds);
			else{
				G_config_playlist.push("cueVideoByUrl"+SPL+_mediaContentUrl+SPL+_startSeconds);
			}//if
		}//fn
		public function loadVideoByUrl(_mediaContentUrl:String, _startSeconds:Number=0):void{
			if(inited && G_PlayerReady) G_player.loadVideoByUrl(_mediaContentUrl, _startSeconds);
			else{
				G_config_playlist.push("loadVideoByUrl"+SPL+_mediaContentUrl+SPL+_startSeconds);
			}//if
		}//fn
		public function cuePlaylist(_playlist:*, _index:Number=0, _startSeconds:Number=0, _suggestedQuality:String=DEFAULT):void{
			if(inited && G_PlayerReady) G_player.cuePlaylist(_playlist, _index, _startSeconds, _suggestedQuality);
			else{
				G_config_playlist.push("cuePlaylist"+SPL+_playlist+SPL+_index+SPL+_startSeconds+SPL+_suggestedQuality);
			}//if
		}//fn
		public function loadPlaylist(_playlist:*, _index:Number=0, _startSeconds:Number=0, _suggestedQuality:String=DEFAULT):void{
			if(inited && G_PlayerReady) G_player.loadPlaylist(_playlist, _index, _startSeconds, _suggestedQuality);
			else{
				G_config_playlist.push("loadPlaylist"+SPL+_playlist+SPL+_index+SPL+_startSeconds+SPL+_suggestedQuality);
			}//if
		}//fn
		public function playVideo():void{
			if(inited && G_PlayerReady) G_player.playVideo();
		}//fn
		public function pauseVideo():void{
			if(inited && G_PlayerReady) G_player.pauseVideo();
		}//fn
		public function stopVideo():void{
			if(inited && G_PlayerReady) G_player.stopVideo();
		}//fn
		public function seekTo(_seconds:Number, _allowSeekAhead:Boolean=true):void{
			if(inited && G_PlayerReady) G_player.seekTo(_seconds, _allowSeekAhead);
		}//fn
		public function nextVideo():void{
			if(inited && G_PlayerReady) G_player.nextVideo();
		}//fn
		public function previousVideo():void{
			if(inited && G_PlayerReady) G_player.previousVideo();
		}//fn
		public function playVideoAt(_index:Number=0):void{
			if(inited && G_PlayerReady) G_player.playVideoAt(_index);
		}//fn
		public function mute():void{
			if(inited && G_PlayerReady) G_player.mute();
		}//fn
		public function unMute():void{
			if(inited && G_PlayerReady) G_player.unMute();
		}//fn
		public function get isMuted():Boolean{return G_player.isMuted()}
		public function setVolume(_volume:Number):void{
			if(inited && G_PlayerReady) G_player.setVolume(_volume);
		}//fn
		public function get getVolume():Number{return G_player.getVolume()}
		public function setSize(_tWidth:Number, _tHeight:Number):void{
			if(inited && G_PlayerReady) G_player.setSize(_tWidth, _tHeight);
		}//fn
		public function setLoop(_loopPlaylists:Boolean):void{
			if(inited && G_PlayerReady) G_player.setLoop(_loopPlaylists);
		}//fn
		public function setShuffle(_shufflePlaylist:Boolean):void{
			if(inited && G_PlayerReady) G_player.setShuffle(_shufflePlaylist);
		}//fn
		public function get getVideoBytesLoaded():Number{return G_player.getVideoBytesLoaded()}
		public function get getVideoBytesTotal():Number{return G_player.getVideoBytesTotal()}
		public function get getVideoStartBytes():Number{return G_player.getVideoStartBytes()}
		public function get getPlayerState():Number{return G_player.getPlayerState()}
		public function get getCurrentTime():Number{return G_player.getCurrentTime()}
		public function get getPlaybackQuality():String{return G_player.getPlaybackQuality()}
		public function setPlaybackQuality(_suggestedQuality:String):void{
			if(inited && G_PlayerReady) G_player.setPlaybackQuality(_suggestedQuality);
		}//fn
		public function get getAvailableQualityLevels():Array{return G_player.getAvailableQualityLevels()}
		public function get getDuration():Number{return G_player.getDuration()}
		public function get getVideoUrl():String{return G_player.getVideoUrl()}
		public function get getVideoEmbedCode():String{return G_player.getVideoEmbedCode()}
		public function get getPlaylist():Array{return G_player.getPlaylist()}
		public function get getPlaylistIndex():Number{return G_player.getPlaylistIndex()}
		
		
		
		
		//
		// Handler
		//
		private function handleAddStage(e:Event):void{
			this.removeEventListener(Event.ADDED_TO_STAGE, handleAddStage);
			this.addEventListener(Event.REMOVED_FROM_STAGE, RELEASE);
		}//fn
		private function handleOnLoaderInit(event:Event):void {
			G_loader.content.addEventListener("onReady", handleOnPlayerReady);
			G_loader.content.addEventListener("onError", handleOnPlayerError);
			G_loader.content.addEventListener("onStateChange", handleOnPlayerStateChange);
			G_loader.content.addEventListener("onPlaybackQualityChange", handleOnVideoPlaybackQualityChange);
		}//fn
		private function handleOnPlayerReady(event:Event):void {
			// Event.data contains the event parameter, which is the Player API ID 
			debug.msg("youtubeAPI > handleOnPlayerReady :"+ Object(event).data);
			G_player=G_loader.content;
			// player is loaded
			this.addChild(Sprite(G_player));
			G_PlayerReady=true;
			this.dispatchEvent(new LoadEvent(LoadEvent.ONLOAD));
			// Once this event has been dispatched by the player, we can use
			// cueVideoById, loadVideoById, cueVideoByUrl and loadVideoByUrl
			// to load a particular YouTube video.
			
			// Start to import the video in list.
			// Asshole! You should load the video after the player has been loaded.
			debug.msg("youtubeAPI : Playlist in queue : "+ G_config_playlist.length);
			if(G_config_playlist.length>0){
				var _ta:Array=new Array();
				for(var i:int=0;i<G_config_playlist.length;i++){
					_ta = G_config_playlist[i].split(SPL);
					switch(_ta[0]){
						default : debug.msg("youtubeAPI > handleOnPlayerReady : load Playlist fail - ["+ _ta.join(',') +"]"); break;
						case "cueVideoById":	this.cueVideoById(_ta[1],_ta[2],_ta[3]); break;
						case "loadVideoById":	this.loadVideoById(_ta[1],_ta[2],_ta[3]); break;
						case "cueVideoByUrl":	this.cueVideoByUrl(_ta[1],_ta[2]); break;
						case "loadVideoByUrl":	this.loadVideoByUrl(_ta[1],_ta[2]); break;
						case "cuePlaylist":		this.cuePlaylist(_ta[1],_ta[2],_ta[3],_ta[4]); break;
						case "loadPlaylist":	this.loadPlaylist(_ta[1],_ta[2],_ta[3],_ta[4]); break;
					}//case
				}//for
				G_config_playlist=new Array(); // Clear up
			}//if
		}//fn
		private function handleOnPlayerError(event:Event):void {
			// Event.data contains the event parameter, which is the error code
			debug.msg("player error:"+ Object(event).data);
			this.dispatchEvent(new LoadEvent(LoadEvent.FAIL, {error:"youtubeAPI : player error:"+ Object(event).data}));
		}//fn
		private function handleOnPlayerStateChange(event:Event):void {
			// Event.data contains the event parameter, which is the new player state
			debug.msg("player state:"+ Object(event).data);
		}//fn
		private function handleOnVideoPlaybackQualityChange(event:Event):void {
			// Event.data contains the event parameter, which is the new video quality
			debug.msg("video quality:"+ Object(event).data);
		}//fn
	}//class
}//package